
from django.db.models import Q
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response

from coderedis import codeRedis
from .models import Category, Course, ActivityCourse
from .serializers import CategorySerializer, CategoryModel, courseSerializer, CourseIndexesSerializer, \
    ActivityCourseSerializer
from rest_framework.pagination import PageNumberPagination
from drf_haystack.viewsets import HaystackViewSet
from datetime import datetime

class CoursePagination(PageNumberPagination):
    page_size = 5
    page_size_query_param = 'page_size'


class CateViewSet(viewsets.ModelViewSet):
    pagination_class = CoursePagination

    # 1.获取一级分类和二级分类数据
    @action(methods=['get'], detail=False)
    def cate(self, request):
        categorys = Category.objects.filter(is_show=1, parent=None)
        serializer = CategorySerializer(categorys, many=True).data
        # 方案1 ：循环追加孩子数据
        for item in serializer:
            # item['children'] = CourseSerializer(Category.objects.filter(parent=item['id']), many=True).data
            item['children'] = item["children"][:3]  # 取3个
        # 方案2：使用序列化器嵌套解决，代码见model和serializer文件
        return Response({
            'code': 200,
            'message': 'success',
            'data': serializer
        })

    #  2.获取某个一级分类下的所有子分类和对应推荐课程
    @action(methods=['get'], detail=False)
    def cate_child(self, request):
        cate_id = request.query_params.get('cate_id', None)
        if not cate_id:
            return Response({
                'code': 400,
                'message': '参数错误'
            })
        cate = Category.objects.get(id=cate_id)
        serializer = CategorySerializer(cate).data
        # 追加课程推荐数据
        secondID = [item['id'] for item in serializer['children']]
        serializer["course"] = courseSerializer(Course.objects.filter(cate_id__in=secondID, is_home=True),
                                                many=True).data[:4]
        return Response({
            'code': 200,
            'message': 'success',
            'data': serializer
        })

    # 3.获取一级分类，不需要二级分类，修改使用的序列化器即可
    @action(methods=['get'], detail=False)
    def cate_list(self, request):
        categorys = Category.objects.filter(is_show=1, parent=None)
        serializer = CategoryModel(categorys, many=True).data
        return Response({
            'code': 200,
            'message': 'success',
            'data': serializer
        })

    # 4.定义根据全部和筛选条件查询二级分类接口
    @action(methods=['get'], detail=False)
    def cate_child_list(self, request):
        cate_id = request.query_params.get('cate_id', None)
        if not cate_id:
            return Response({
                'code': 400,
                'message': '参数错误'
            }, status=400)
        if cate_id == '0':
            categorys = Category.objects.exclude(is_show=1, parent=None)
        else:
            categorys = Category.objects.filter(is_show=1, parent=cate_id)
        serializer = CategoryModel(categorys, many=True).data
        return Response({
            'code': 200,
            'message': 'success',
            'data': serializer
        })

    # 5.定义课程分页列表，支持多条件筛选
    @action(methods=['get'], detail=False)
    def course_list(self, request):
        # 获取课程方向、分类、难度、排序查询条件参数
        direction = request.query_params.get('direction', None)
        category = request.query_params.get('category', None)
        level = request.query_params.get('level', None)
        order = request.query_params.get('order')

        # 添加查询条件
        query = Q(is_show=1)
        if direction is not None and category is not None:
            query &= Q(cate=category)
        if direction is not None and category is None:
            # secondCate:[1,2,3,4]
            secondCate = Category.objects.filter(is_show=1, parent=direction).values_list("id", flat=True)
            query &= Q(cate__in=secondCate)
        if level is not None:
            query &= Q(level=level)
        # 如果存在排序就按照价格，反之按照orders字段排序即可
        if order is not None:
            if order == '1':
                order = '-price'
            else:
                order = 'price'
        else:
            order = 'orders'

        courses = Course.objects.filter(query).order_by(order)
        pageData = self.paginate_queryset(courses)
        if pageData is not None:
            serializer = courseSerializer(pageData, many=True).data
        else:
            serializer = courseSerializer(courses, many=True).data
        return Response({
            'code': 200,
            'message': 'success',
            'data': serializer
        })

    # 6.获取搜索热词
    @action(methods=['get'], detail=False)
    def get_hot_words(self, request):
        """
        获取搜索热词
        :param request:
        :return:
        """
        hot_words = codeRedis.getWord()
        if not hot_words:
            return Response({
                'code': 400,
                'message': '没有热词数据',
                'data': []
            })
        return Response({
            'code': 200,
            'message': 'success',
            'data': hot_words
        })

    # 7.获取商品详情
    @action(methods=['GET'], detail=False)
    def course_detail(self, request):
        course_id = request.query_params.get('id')
        course = Course.objects.filter(id=course_id).first()
        if not course:
            return Response({
                'code': 400,
                'message': '没有此课程数据',
                'data': {}
            })
        serializer = courseSerializer(course).data
        activity = ActivityCourse.objects.filter(course=course_id).first()
        if activity:
            activitySer = ActivityCourseSerializer(activity).data
            now = datetime.now().timestamp()
            start_time = datetime.strptime(activitySer['activity']['start_time'], "%Y-%m-%dT%H:%M:%S%z").timestamp()
            end_time = datetime.strptime(activitySer['activity']['end_time'], "%Y-%m-%dT%H:%M:%S%z").timestamp()
            if start_time <= now <= end_time:
                serializer["discount"] = activitySer
        return Response({
            'code': 200,
            'message': 'success',
            'data': serializer
        })


# 2.定义搜索引擎视图
class CourseSearchViewSet(HaystackViewSet):
    index_models = [Course]
    serializer_class = CourseIndexesSerializer
    pagination_class = CoursePagination

    # 重写列表接口，收集搜索关键词
    def list(self, request, *args, **kwargs):
        word = request.query_params.get('text')
        codeRedis.setWord(word)
        return super().list(request)
